還記得我們在 Day 13 的例子嗎?
有個 Input 的 UI 元件,且它有以下 [Invalid / Valid]、[Disabled / Enabled]、[Changed / Unchanged],這 3 類型的特點
我們假設
今天就即將在 XState 實作,寫出 machineConfig 來!
你說 XState 的 config 如何描述 Parallel State 呢?
以下是一個 一般的 FSM
{
id: "myId",
initial: "state1",
states: {
state1: {
on: {
event1: { target: "state2" }
}
},
state2: {
on: {
event2: { target: "state1" }
}
}
}
}
我們只要在 states
前面加上一組 [key / value] -> type: 'parallel',
,並在上面原本 state1
、state2
之間,原本直接寫下 [on + event1], [on + event2] 改成另外一組新的子狀態機定義
TLDR 視覺化互動狀態機
id: "myId",
+ type: "parallel",
- initial: "state1",
states: {
state1: {
+ initial: "state1-1",
+ states: {
+ "state1-1": {
+ on: {
+ "event1-1": { target: "state1-2" },
+ },
+ },
+ "state1-2": {
+ on: {
+ "event1-2": { target: "state1-1" },
+ },
+ },
+ },
},
state2: {
+ initial: "state2-1",
+ states: {
+ "state2-1": {
+ on: {
+ "event2-1": { target: "state2-2" },
+ },
+ },
+ "state2-2": {
+ on: {
+ "event2-2": { target: "state2-1" },
+ },
+ },
+ },
},
},
});
如此就可以完成一個簡易的平行狀態機
題外話,XState 官方也有提供視覺化工具 Visualizer ,讓你可以簡易的撰寫完 machineConfig
後,就能直接看到 State Chart 並且能與之互動
剛剛的範例可參考視覺化互動狀態機
另外我們現在會看 Visualizer 上使用到舊版 API Machine
,其實 XState 目前也已經有新版的 Visualizer 了,只不過我還不太熟悉如何分享,所以在這邊先用舊版的分享
舊版 https://xstate.js.org/viz
新版 https://stately.ai/viz
除了新版的 Visualizer,官方也提供了 DX 更好的 tool, inspect 套件,也希望能在這次鐵人賽有機會能介紹到
const inputMachine = createMachine({
id: "inputMachine_v1",
type: "parallel",
states: {
valid: {
initial: "valid",
states: {
invalid: {
on: {
VALIDATE: { target: "valid" },
},
},
valid: {
on: {
INVALIDATE: { target: "invalid" },
},
},
},
},
enabled: {
initial: "enabled",
states: {
disabled: {
on: {
ENABLE: { target: "enabled" },
},
},
enabled: {
on: {
DISABLE: { target: "disabled" },
},
},
},
},
changed: {
initial: "unchanged",
states: {
unchanged: {
on: {
CHANGE: { target: "changed" },
},
},
changed: {
on: {
REVERT_CHANGE: { target: "unchanged" },
},
},
},
},
},
});
如此我們便完成了 Day 13 的例子。
https://xstate.js.org/docs/guides/parallel.html